home *** CD-ROM | disk | FTP | other *** search
/ Power Hacker 2003 / Power_Hacker_2003.iso / Exploit and vulnerability / w00w00 / sectools / fragrouter / print.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-07-26  |  9.4 KB  |  376 lines

  1. /*
  2.   print.c
  3.  
  4.   Dug Song <dugsong@anzen.com>
  5.  
  6.   Copyright (c) 1999 Anzen Computing. All rights reserved.
  7.  
  8.   Redistribution and use in source and binary forms, with or without
  9.   modification, are permitted provided that the following conditions
  10.   are met:
  11.   
  12.   1. Redistributions of source code must retain the above copyright
  13.      notice, this list of conditions and the following disclaimer.
  14.   2. Redistributions in binary form must reproduce the above copyright
  15.      notice, this list of conditions and the following disclaimer in the
  16.      documentation and/or other materials provided with the distribution.
  17.   3. All advertising materials mentioning features or use of this software
  18.      must display the following acknowledgement:
  19.      This product includes software developed by Anzen Computing.
  20.   4. Neither the name of Anzen Computing nor the names of its
  21.      contributors may be used to endorse or promote products derived
  22.      from this software without specific prior written permission.
  23.  
  24.   THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
  25.   WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  26.   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  27.   IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  28.   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  29.   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  30.   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  31.   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  32.   IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  33.   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  34.   ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35.  
  36.   $Id: print.c,v 1.2 1999/05/27 02:39:38 dugsong Exp $
  37. */
  38.  
  39. #ifdef STDC_HEADERS
  40. #include <stdio.h>
  41. #endif
  42. #include <libnet.h>
  43. #include "print.h"
  44.  
  45. /* The following code is an adaptation of the print-* code in tcpdump. */
  46.  
  47. /* Compatibility */
  48. #ifndef TCPOPT_WSCALE
  49. #define TCPOPT_WSCALE           3       /* window scale factor (rfc1072) */
  50. #endif
  51. #ifndef TCPOPT_SACKOK
  52. #define TCPOPT_SACKOK           4       /* selective ack ok (rfc2018) */
  53. #endif
  54. #ifndef TCPOPT_SACK
  55. #define TCPOPT_SACK             5       /* selective ack (rfc2018) */
  56. #endif
  57. #ifndef TCPOLEN_SACK
  58. #define TCPOLEN_SACK            8       /* length of a SACK block */
  59. #endif
  60. #ifndef TCPOPT_ECHO
  61. #define TCPOPT_ECHO             6       /* echo (rfc1072) */
  62. #endif
  63. #ifndef TCPOPT_ECHOREPLY
  64. #define TCPOPT_ECHOREPLY        7       /* echo (rfc1072) */
  65. #endif
  66. #ifndef TCPOPT_TIMESTAMP
  67. #define TCPOPT_TIMESTAMP        8       /* timestamps (rfc1323) */
  68. #endif
  69. #ifndef TCPOPT_CC
  70. #define TCPOPT_CC               11      /* T/TCP CC options (rfc1644) */
  71. #endif
  72. #ifndef TCPOPT_CCNEW
  73. #define TCPOPT_CCNEW            12      /* T/TCP CC options (rfc1644) */
  74. #endif
  75. #ifndef TCPOPT_CCECHO
  76. #define TCPOPT_CCECHO           13      /* T/TCP CC options (rfc1644) */
  77. #endif
  78.  
  79. #ifndef IP_OFFMASK
  80. #define IP_OFFMASK    0x1fff
  81. #endif
  82.  
  83. #define EXTRACT_16BITS(p) \
  84.         ((u_short)ntohs(*(u_short *)(p)))
  85. #define EXTRACT_32BITS(p) \
  86.         ((u_long)ntohl(*(u_long *)(p)))
  87.  
  88. void
  89. print_ip(unsigned char *bp, int length)
  90. {
  91.   struct ip *iph;
  92.   u_int ip_off, ip_hl, ip_len;
  93.  
  94.   iph = (struct ip *)bp;
  95.  
  96.   if (length < IP_H) {
  97.     printf("truncated-ip %d", length);
  98.     return;
  99.   }
  100.   ip_hl = iph->ip_hl * 4;
  101.   ip_len = ntohs(iph->ip_len);
  102.  
  103.   if (length < ip_len) {
  104.     printf("truncated-ip - %d bytes missing!", ip_len - length);
  105.     return;
  106.   }
  107.   ip_off = ntohs(iph->ip_off);
  108.  
  109.   /* Handle first fragment. */
  110.   if ((ip_off & IP_OFFMASK) == 0) {
  111.     switch (iph->ip_p) {
  112.  
  113.     case IPPROTO_TCP:
  114.       print_tcp(bp, ip_len);
  115.       break;
  116.  
  117.     case IPPROTO_UDP:
  118.       print_udp(bp, ip_len);
  119.       break;
  120.  
  121.     case IPPROTO_ICMP:
  122.       print_icmp(bp, ip_len);
  123.       break;
  124.  
  125.     default:
  126.       printf("%s > %s:", libnet_host_lookup(iph->ip_src.s_addr, 0),
  127.          libnet_host_lookup(iph->ip_dst.s_addr, 0));
  128.       printf(" ip-proto-%d %d", iph->ip_p, ip_len);
  129.       break;
  130.     }
  131.   }
  132.   /* Handle more frags. */
  133.   if (ip_off & (IP_MF|IP_OFFMASK)) {
  134.     if (ip_off & IP_OFFMASK)
  135.       printf("%s > %s:", libnet_host_lookup(iph->ip_src.s_addr, 0),
  136.          libnet_host_lookup(iph->ip_dst.s_addr, 0));
  137.     
  138.     printf(" (frag %d:%d@%d%s)", ntohs(iph->ip_id), ip_len - ip_hl,
  139.        (ip_off & IP_OFFMASK) << 3, (ip_off & IP_MF) ? "+" : "");
  140.   }
  141.   /* Handle don't frags. */
  142.   else if (ip_off & IP_DF) printf(" (DF)");
  143.     
  144.   if (iph->ip_tos) printf(" [tos 0x%x]", (int)iph->ip_tos);
  145.   if (iph->ip_ttl <= 1) printf(" [ttl %d]", (int)iph->ip_ttl);
  146. }
  147.  
  148. void
  149. print_udp(unsigned char *bp, int length)
  150. {
  151.   struct ip *iph;
  152.   struct udphdr *udph;
  153.  
  154.   iph = (struct ip *)bp;
  155.   udph = (struct udphdr *)(bp + (iph->ip_hl * 4));
  156.  
  157.   printf("%s.%d > %s.%d:", libnet_host_lookup(iph->ip_src.s_addr, 0),
  158.      ntohs(udph->uh_sport), libnet_host_lookup(iph->ip_dst.s_addr, 0),
  159.      ntohs(udph->uh_dport));
  160.  
  161.   printf(" udp %d", ntohs(udph->uh_ulen) - UDP_H);
  162. }
  163.  
  164. void
  165. print_icmp(unsigned char *bp, int length)
  166. {
  167.   struct ip *iph;
  168.   struct libnet_icmp_hdr *icmph;
  169.  
  170.   iph = (struct ip *)bp;
  171.   icmph = (struct libnet_icmp_hdr *)(bp + (iph->ip_hl * 4));
  172.  
  173.   printf("%s > %s:", libnet_host_lookup(iph->ip_src.s_addr, 0),
  174.      libnet_host_lookup(iph->ip_dst.s_addr, 0));
  175.  
  176.   printf(" icmp: type %d code %d", icmph->icmp_type, icmph->icmp_code);
  177. }
  178.   
  179. void
  180. print_tcp(unsigned char *bp, int length)
  181. {
  182.   struct ip *iph;
  183.   struct tcphdr *tcph;
  184.   u_short sport, dport, win, urp;
  185.   u_long seq, ack;
  186.   int len, tcp_hl;
  187.   register char ch;
  188.  
  189.   iph = (struct ip *)bp;
  190.   tcph = (struct tcphdr *)(bp + (iph->ip_hl * 4));
  191.   len = length - (iph->ip_hl * 4);
  192.  
  193.   if (len < TCP_H) {
  194.     printf("truncated-tcp %d", len);
  195.     return;
  196.   }
  197.   sport = ntohs(tcph->th_sport);
  198.   dport = ntohs(tcph->th_dport);
  199.   seq = ntohl(tcph->th_seq);
  200.   ack = ntohl(tcph->th_ack);
  201.   win = ntohs(tcph->th_win);
  202.   urp = ntohs(tcph->th_urp);
  203.   tcp_hl = tcph->th_off * 4;
  204.  
  205.   printf("%s.%d > %s.%d: ", libnet_host_lookup(iph->ip_src.s_addr, 0), sport,
  206.      libnet_host_lookup(iph->ip_dst.s_addr, 0), dport);
  207.  
  208.   if (tcph->th_flags & (TH_SYN|TH_FIN|TH_RST|TH_PUSH)) {
  209.     if (tcph->th_flags & TH_SYN) putchar('S');
  210.     if (tcph->th_flags & TH_FIN) putchar('F');
  211.     if (tcph->th_flags & TH_RST) putchar('R');
  212.     if (tcph->th_flags & TH_PUSH) putchar('P');
  213.   }
  214.   else putchar('.');
  215.   
  216.   if (tcp_hl > len) {
  217.     printf(" [bad hdr length]");
  218.     return;
  219.   }
  220.   len -= tcp_hl;
  221.  
  222.   if (len > 0 || tcph->th_flags & (TH_SYN | TH_FIN | TH_RST))
  223.     printf(" %lu:%lu(%d)", seq, seq + len, len);
  224.  
  225.   if (tcph->th_flags & TH_ACK) printf(" ack %lu", ack);
  226.   printf(" win %d", win);
  227.   if (tcph->th_flags & TH_URG) printf(" urg %d", urp);
  228.  
  229.   /* Handle options. */
  230.   if ((tcp_hl -= TCP_H) > 0) {
  231.     register const u_char *cp;
  232.     register int i, opt, len, datalen;
  233.     
  234.     cp = (const u_char *)tcph + TCP_H;
  235.     putchar(' ');
  236.     ch = '<';
  237.  
  238. #define ZEROLENOPT(o) ((o) == TCPOPT_EOL || (o) == TCPOPT_NOP)
  239.     
  240.     while (tcp_hl > 0) {
  241.       putchar(ch);
  242.       opt = *cp++;
  243.       if (ZEROLENOPT(opt))
  244.     len = 1;
  245.       else {
  246.     len = *cp++;    /* total including type, len */
  247.     if (len < 2 || len > tcp_hl)
  248.       goto bad;
  249.     --tcp_hl;         /* account for length byte */
  250.       }
  251.       --tcp_hl;           /* account for type byte */
  252.       datalen = 0;
  253.       
  254. /* Bail if "l" bytes of data are not left or were not captured  */
  255. #define LENCHECK(l) { if ((l) > tcp_hl) goto bad; }
  256.       
  257.       switch (opt) {
  258.  
  259.       case TCPOPT_MAXSEG:
  260.     printf("mss");
  261.     datalen = 2;
  262.     LENCHECK(datalen);
  263.     printf(" %u", EXTRACT_16BITS(cp));
  264.     break;
  265.     
  266.       case TCPOPT_EOL:
  267.     printf("eol");
  268.     break;
  269.     
  270.       case TCPOPT_NOP:
  271.     printf("nop");
  272.     break;
  273.     
  274.       case TCPOPT_WSCALE:
  275.     printf("wscale");
  276.     datalen = 1;
  277.     LENCHECK(datalen);
  278.     printf(" %u", *cp);
  279.     break;
  280.     
  281.       case TCPOPT_SACKOK:
  282.     printf("sackOK");
  283.     if (len != 2)
  284.       printf("[len %d]", len);
  285.     break;
  286.     
  287.       case TCPOPT_SACK:
  288.     datalen = len - 2;
  289.     if ((datalen % TCPOLEN_SACK) != 0 || !(tcph->th_flags & TH_ACK)) {
  290.       printf("malformed sack ");
  291.       printf("[len %d] ", datalen);
  292.       break;
  293.     }
  294.     printf("sack %d ", datalen/TCPOLEN_SACK);
  295.     break;
  296.     
  297.       case TCPOPT_ECHO:
  298.     printf("echo");
  299.     datalen = 4;
  300.     LENCHECK(datalen);
  301.     printf(" %lu", EXTRACT_32BITS(cp));
  302.     break;
  303.     
  304.       case TCPOPT_ECHOREPLY:
  305.     printf("echoreply");
  306.     datalen = 4;
  307.     LENCHECK(datalen);
  308.     printf(" %lu", EXTRACT_32BITS(cp));
  309.     break;
  310.     
  311.       case TCPOPT_TIMESTAMP:
  312.     printf("timestamp");
  313.     datalen = 8;
  314.     LENCHECK(4);
  315.     printf(" %lu", EXTRACT_32BITS(cp));
  316.     LENCHECK(datalen);
  317.     printf(" %lu", EXTRACT_32BITS(cp + 4));
  318.     break;
  319.     
  320.       case TCPOPT_CC:
  321.     printf("cc");
  322.     datalen = 4;
  323.     LENCHECK(datalen);
  324.     printf(" %lu", EXTRACT_32BITS(cp));
  325.     break;
  326.     
  327.       case TCPOPT_CCNEW:
  328.     printf("ccnew");
  329.     datalen = 4;
  330.     LENCHECK(datalen);
  331.     printf(" %lu", EXTRACT_32BITS(cp));
  332.     break;
  333.     
  334.       case TCPOPT_CCECHO:
  335.     printf("ccecho");
  336.     datalen = 4;
  337.     LENCHECK(datalen);
  338.     printf(" %lu", EXTRACT_32BITS(cp));
  339.     break;
  340.     
  341.       default:
  342.     printf("opt-%d:", opt);
  343.     datalen = len - 2;
  344.     for (i = 0; i < datalen; ++i) {
  345.       LENCHECK(i);
  346.       printf("%02x", cp[i]);
  347.     }
  348.     break;
  349.       }
  350.       /* Account for data printed */
  351.       cp += datalen;
  352.       tcp_hl -= datalen;
  353.       
  354.       /* Check specification against observed length */
  355.       ++datalen;                /* option octet */
  356.       if (!ZEROLENOPT(opt))
  357.     ++datalen;              /* size octet */
  358.       if (datalen != len)
  359.     printf("[len %d]", len);
  360.       ch = ',';
  361.       if (opt == TCPOPT_EOL)
  362.     break;
  363.     }
  364.     putchar('>');
  365.   }
  366.   return;
  367.   
  368.  bad:
  369.   fputs("[bad opt]", stdout);
  370.   if (ch != '\0')
  371.     putchar('>');
  372.   return;
  373. }
  374.  
  375.       
  376.